﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CourseDesign_02;

namespace FundamentalsOfCompiling
{
    class Syntax
    {
        private List<TokenType> list;//这个是token序列的引用
        public Global global;
        public TokenType token;//记录当前的token
        private string temp_name;
        int line0;//行号
        static int indentno = 0;//记录缩进,初始化是0
        static void increase() { indentno += 1; }
        static void decrease() { indentno -= 1; }
        int fp_num = 0;    /*输出时记录token个数的变量*/
        private treeNode tree;
        private Midiator midiator = null;
        public Syntax(Global global, List<TokenType> list)
        {
            fp_num = 0;
            this.global = global;
            global.operateError = false;
            this.list = list;
        }
        public treeNode parse()
        {

            fp_num = 0;    /*输出时记录token个数的变量*/
            global.operateError = false;
            treeNode t = null;
            ReadNextToken();
            t = program();
            if (token.Lex != LexType.ENDFILE1)
                printError("Code ends before file\n");
            this.tree = t;
            return t;
        }
        public void printError(string str)
        {
            midiator.WriteLine(str);
        }
        treeNode newNode()
        {
            treeNode t = new treeNode();
            int i;
            if (t == null)
            {
                printError("创建节点时出错。");
                global.operateError = true;
               
            }
            else
            {
                for (i = 0; i < treeNode.MAXCHILDREN; i++)
                    t.child[i] = null;
                t.sibling = null;
                t.lineno = line0;//当前节点的行号设置为当前行号
                for (i = 0; i < 10; i++)
                {
                    t.name[i] = null;
                }
            }
            return t;
        }

        treeNode newSpecificNode(NodeKind kind)
        {
            treeNode t = newNode();
            t.nodekind = kind;
            return t;
        }
        treeNode newStmtNode(StmtKind kind)
        {
            treeNode t = newNode();
            t.nodekind = NodeKind.StmtK;
            t.kind.stmt = kind;
            return t;
        }
        treeNode newExpNode(ExpKind kind)
        {
            treeNode t = newNode();
            t.nodekind = NodeKind.ExpK;
            t.kind.exp = kind;
            return t;
        }

        public void setList(List<TokenType> li)
        {
            this.list = li;
        }

        public List<TokenType> getList()
        {
            return list;
        }

        public void setListnull()
        {
            list = null;
        }

        public void ReadNextToken() {
            if (list == null)
            {
                midiator.WriteLine("list is null");
            }
            else
            {
                while (true)
                {
                    if (list[fp_num].Lex == LexType.CRT) fp_num++;
                    else break;
                }
                token = list[fp_num];
                fp_num++;
            }
        }
        void printSpaces()
        {
            int i;
            for (i = 0; i < indentno; i++)
                midiator.Write("  ");
        }
        public void printTree(Midiator m) 
        { 
            this.midiator = m; 
            printTree(this.tree); 
        }
        public void printTree(treeNode tree) {
            int i;
            increase();
            while (tree != null)
            {
                if (tree.lineno != 0)
                    printSpaces();

                switch (tree.nodekind)
                {
                    case NodeKind.ProK:
                        midiator.WriteLine("程序的结构如下：");
                        break;
                    case NodeKind.PheadK:
                        {
                            //midiator.Write("  程序的开始部分： "+"PheadK");
                            midiator.WriteLine("程序名：" + tree.name[0]);
                        }
                        break;
                    case NodeKind.DecK:
                        {
                            //midiator.WriteLine( "声明部分：");
                            //if (tree.attr.ProcAttr.paramt == ParamType.varparamType)
                            //    midiator.Write("var param:");
                            //if (tree.attr.ProcAttr.paramt == ParamType.valparamType)
                            //    midiator.Write("value param:");
                            switch (tree.kind.dec)
                            {
                                case DecKind.ArrayK:
                                    {
                                        midiator.Write("数组类型定义");
                                        midiator.Write("下界：" + tree.attr.ArrayAttr.low + " ");
                                        midiator.Write("上界：" + tree.attr.ArrayAttr.up + " ");
                                        if (tree.attr.ArrayAttr.childtype == DecKind.CharK)
                                            midiator.Write("成员类型：字符");
                                        else if (tree.attr.ArrayAttr.childtype == DecKind.IntegerK)
                                            midiator.Write("成员类型：整数");
                                    };
                                    break;
                                case DecKind.CharK:
                                    midiator.Write("字符类型");
                                    break;
                                case DecKind.IntegerK:
                                    midiator.Write("整数类型 ");
                                    break;
                                case DecKind.RecordK:
                                    midiator.Write("记录类型 ");
                                    break;
                                case DecKind.IdK:
                                    midiator.Write("自定义类型 ");
                                    midiator.Write(tree.attr.type_name);
                                    break;
                                default:
                                    midiator.Write("Error1!");
                                    global.operateError = true;
                                    break;
                            }   //  switch (tree.kind.dec)

                            if (tree.idnum != 0)
                            {
                                int iu = 0;
                                for (; iu <= (tree.idnum); iu++)
                                {
                                    midiator.Write(" " + tree.name[iu] + " ");
                                }
                            }   //  if
                            else
                            {
                                midiator.Write("wrong!no var!\n");
                                global.operateError = true;
                            }    //  else
                        }
                        break;  //  case NodeKind.DecK:
                    case NodeKind.TypeK:
                        midiator.Write("类型声明 ");
                        break;

                    case NodeKind.VarK:
                        midiator.Write("变量声明 ");
                        //if(tree.table[0]!=null)
                        //    midiator.WriteLine("%d  %d  ",tree.table[0].attrIR.More.VarAttr.off,tree.table[0].attrIR.More.VarAttr.level);
                        break;

                    case NodeKind.ProcDecK:
                        midiator.Write("函数声明  ");
                        midiator.Write(tree.name[0]);
                        //if(tree.table[0]!=null)
                        //    midiator.WriteLine("%d %d %d  ",tree.table[0].attrIR.More.ProcAttr.mOff,tree.table[0].attrIR.More.ProcAttr.nOff,tree.table[0].attrIR.More.ProcAttr.level);
                        break;

                    case NodeKind.StmLK:
                        midiator.Write("语句序列 "); break;

                    case NodeKind.StmtK:
                        {
                            // midiator.Write(" 一个语句 ");
                            switch (tree.kind.stmt)
                            {
                                case StmtKind.IfK:
                                    midiator.Write("If语句 ");
                                    break;
                                case StmtKind.WhileK:
                                    midiator.Write("While语句 ");
                                    break;

                                case StmtKind.AssignK:
                                    midiator.Write("赋值语句 ");
                                    break;

                                case StmtKind.ReadK:
                                    midiator.Write("输入语句 ");
                                    midiator.Write(tree.name[0]);
                                    //if(tree.table[0]!=null)
                                    //    midiator.WriteLine("%d   %d  ",tree.table[0].attrIR.More.VarAttr.off,tree.table[0].attrIR.More.VarAttr.level);
                                    break;

                                case StmtKind.WriteK:
                                    midiator.Write("输出语句 "); break;

                                case StmtKind.CallK:
                                    midiator.Write("函数调用语句 ");
                                    midiator.Write(tree.name[0]);
                                    break;

                                case StmtKind.ReturnK:
                                    midiator.Write("返回语句 "); break;

                                default:
                                    midiator.Write("Error2!");
                                    global.operateError = true;
                                    break;
                            }
                        }; break;
                    case NodeKind.ExpK:
                        {
                            //midiator.Write( " 表达式 ");
                            switch (tree.kind.exp)
                            {
                                case ExpKind.OpK:
                                    {
                                        midiator.Write("操作符 ");
                                        switch (tree.attr.ExpAttr.op)
                                        {
                                            case LexType.EQ: midiator.Write("="); break;
                                            case LexType.LT: midiator.Write("<"); break;
                                            case LexType.PLUS: midiator.Write("+"); break;
                                            case LexType.MINUS: midiator.Write("-"); break;
                                            case LexType.TIMES: midiator.Write("*"); break;
                                            case LexType.OVER: midiator.Write("/"); break;
                                            default:
                                                midiator.Write("333333333333333333333333333333333Error!");
                                                global.operateError = true;
                                                break;
                                        }

                                        if (tree.attr.ExpAttr.varkind == VarKind.ArrayMembV)
                                        {
                                            midiator.Write("数组成员 ");
                                            midiator.Write(tree.name[0]);
                                        }
                                    }; break;
                                case ExpKind.ConstK:
                                    midiator.Write("常量 ");
                                    //switch(tree.attr.ExpAttr.varkind)
                                    //{
                                    //    case VarKind.IdV:
                                    //    midiator.Write("标识符 ");
                                    //    midiator.Write( tree.name[0]);
                                    //    break;
                                    //    case VarKind.FieldMembV:
                                    //    midiator.Write("记录域成员  ");
                                    //    midiator.Write( tree.name[0]);
                                    //    break;
                                    //    case VarKind.ArrayMembV:
                                    //    midiator.Write("数组成员  ");
                                    //    midiator.Write( tree.name[0]);
                                    //    break;
                                    //    default: 
                                    //        midiator.Write("var type global.operateError!");
                                    //        global.operateError = true;
                                    //        break;
                                    //}

                                    midiator.Write("  " + tree.attr.ExpAttr.val);
                                    break;
                                case ExpKind.VariK:
                                    // midiator.Write( "变量 ");
                                    switch (tree.attr.ExpAttr.varkind)
                                    {
                                        case VarKind.IdV:
                                            midiator.Write("标识符 ");
                                            midiator.Write(tree.name[0]);
                                            break;
                                        case VarKind.FieldMembV:
                                            midiator.Write("域成员变量 ");
                                            midiator.Write(tree.name[0]);
                                            break;
                                        case VarKind.ArrayMembV:
                                            midiator.Write("数组成员变量 ");
                                            midiator.Write(tree.name[0]);
                                            break;
                                        default:
                                            midiator.Write("22222222222222222222222Error!");
                                            global.operateError = true;
                                            break;
                                    }
                                    //if(tree.table[0]!=null)
                                    //    midiator.Write("%d   %d  ",tree.table[0].attrIR.More.VarAttr.off,tree.table[0].attrIR.More.VarAttr.level);

                                    break;
                                default:
                                    midiator.Write("444444444444444444444444444444444Error4!");
                                    global.operateError = true;
                                    break;
                            }
                        }; break;
                    default:
                        midiator.Write("555555555555555555555555555555555555Error5!");
                        global.operateError = true;
                        break;
                }
                midiator.Write("\n");
                increase();
                for (i = 0; i < treeNode.MAXCHILDREN; i++)
                    printTree(tree.child[i]);
                decrease();
                tree = tree.sibling;
            }
            decrease();
        }
        //match 函数//////////////////////////////////////////////匹配函数///////////////////////////////////////////////////////
        void match(LexType expected)
        {
            if (token.Lex == expected)
            {
                ReadNextToken();
                line0 = token.lineshow;//将当当前行号赋值给line0
            }
            else
            {
                printError("Not match error(匹配错误)");
                ReadNextToken();
            }
        }

        treeNode program()
        {
            treeNode t = programHead();
            treeNode q = declarePart();
            treeNode s = programBody();

            treeNode root = newSpecificNode(NodeKind.ProK);
            if (root != null)
            {
                root.lineno = 0;//没有行号
                if (t != null) root.child[0] = t;
                else printError("A program head is expected!");
                if (q != null) root.child[1] = q;
                if (s != null) root.child[2] = s;
                else printError("A program body is expected!");
            }
            match(LexType.DOT);

            return root;
        }
        treeNode programHead()
        {
            treeNode t = newSpecificNode(NodeKind.PheadK);
            match(LexType.PROGRAM);
            if ((t != null) && (token.Lex == LexType.ID))
            {
                t.lineno = 0;//声明性节点没有行号
                t.name[0] = token.Sem;
            }
            match(LexType.ID);
            return t;
        }
        treeNode declarePart()
        {
            treeNode typeP = newSpecificNode(NodeKind.TypeK);
            treeNode pp = typeP;

            if (typeP != null)
            {
                typeP.lineno = line0;//类型声明的标志节点也没有行号
                treeNode tp1 = typeDec();
                if (tp1 != null)
                    typeP.child[0] = tp1;
                else
                {
                    typeP = null;
                }
            }
            /*变量*/
            treeNode varP = newSpecificNode(NodeKind.VarK);
            varP.lineno = line0;

            if (varP != null)
            {
                varP.lineno = line0;//变量标志节点
                treeNode tp2 = varDec();
                if (tp2 != null)
                    varP.child[0] = tp2;
                else
                {
                    varP = null;
                }
            }
            /*函数*/
            treeNode s = procDec();

            if (s == null) { }

            if (varP == null) { varP = s; }

            if (typeP == null) { pp = typeP = varP; }

            if (typeP != varP)
            {
                typeP.sibling = varP;
                typeP = varP;
            }
            if (varP != s)
            {
                varP.sibling = s;
                varP = s;
            }
            return pp;
        }
        treeNode typeDec()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.TYPE: t = typeDeclaration(); break;
                case LexType.VAR:
                case LexType.PROCEDURE:
                case LexType.BEGIN: break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":Unexpected token is here!");
                    break;
            }
            return t;
        }
        treeNode typeDeclaration()
        {
            match(LexType.TYPE);
            treeNode t = typeDecList();
            if (t == null)
            {
                printError(token + ":a type declaration is expected!");
            }
            return t;
        }
        treeNode typeDecList()
        {
            treeNode t = newSpecificNode(NodeKind.DecK);
            if (t != null)
            {
                t.lineno = line0;
                typeId(t);
                match(LexType.EQ);
                typeName(t);////////////////////////////////////////////////error 
                match(LexType.SEMI);
                treeNode p = typeDecMore();
                if (p != null)
                    t.sibling = p;
            }
            else
            {
                midiator.WriteLine("t is null 488");
            }
            return t;
        }
        treeNode typeDecMore()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.VAR:
                case LexType.PROCEDURE:
                case LexType.BEGIN:
                    break;
                case LexType.ID:
                    t = typeDecList();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }
        void typeId(treeNode t)
        {
            int tnum = (t.idnum);
            if ((token.Lex == LexType.ID) && (t != null))
            {
                t.name[tnum] = token.Sem;
                tnum = tnum + 1;
            }
            t.idnum = tnum;
            match(LexType.ID);
        }
        void typeName(treeNode t)
        {
            if (t != null)
                switch (token.Lex)
                {
                    case LexType.INTEGER:
                    case LexType.CHAR1: baseType(t); break;
                    case LexType.ARRAY:
                    case LexType.RECORD: structureType(t); break;
                    case LexType.ID:
                        t.kind.dec = DecKind.IdK;
                        t.attr.type_name = token.Sem;
                        match(LexType.ID);
                        break;
                    default:
                        ReadNextToken();
                        printError(token.lineshow + ":unexpected token is here!");
                        break;
                }
        }
        void baseType(treeNode t)
        {
            switch (token.Lex)
            {
                case LexType.INTEGER: match(LexType.INTEGER);
                    t.kind.dec = DecKind.IntegerK;
                    break;

                case LexType.CHAR1: match(LexType.CHAR1);
                    t.kind.dec = DecKind.CharK;
                    break;

                default:
                    ReadNextToken();
                    printError(token.lineshow + "unexpected token is here!");
                    break;
            }
        }
        void structureType(treeNode t)
        {
            switch (token.Lex)
            {
                case LexType.ARRAY:
                    arrayType(t);
                    break;
                case LexType.RECORD:
                    t.kind.dec = DecKind.RecordK;
                    recType(t);
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
        }
        //将字符串转化成数字
        public int StrToInt(string str)
        {
            int length = str.Length;
            char c;
            int sum = 0;
            int count = 0;
            for (int j = 0; j < length; j++)
            {
                c = str.ElementAt(j);
                switch (c)
                {
                    case '0': count = 0; break;
                    case '1': count = 1; break;
                    case '2': count = 2; break;
                    case '3': count = 3; break;
                    case '4': count = 4; break;
                    case '5': count = 5; break;
                    case '6': count = 6; break;
                    case '7': count = 7; break;
                    case '8': count = 8; break;
                    case '9': count = 9; break;
                }
                sum = sum * 10 + count;
            }
            return sum;
        }
        void arrayType(treeNode t)
        {
            match(LexType.ARRAY);
            match(LexType.LMIDPAREN);
            if (token.Lex == LexType.INTC)
            {
                t.attr.ArrayAttr.low = StrToInt(token.Sem);//将字符串数字转化成整形的数字
            }
            match(LexType.INTC);
            match(LexType.UNDERANGE);
            if (token.Lex == LexType.INTC)
            {
                t.attr.ArrayAttr.up = StrToInt(token.Sem);
            }
            match(LexType.INTC);
            match(LexType.RMIDPAREN);
            match(LexType.OF);
            baseType(t);
            t.attr.ArrayAttr.childtype = t.kind.dec;
            t.kind.dec = DecKind.ArrayK;
        }
        void recType(treeNode t)
        {
            treeNode p = null;
            match(LexType.RECORD);
            p = fieldDecList();
            if (p != null)
                t.child[0] = p;
            else
                printError(token.lineshow + ":a record body is requested!");
            match(LexType.END);
        }
        treeNode fieldDecList()
        {

            treeNode t = newSpecificNode(NodeKind.DecK);
            treeNode p = null;
            if (t != null)
            {
                t.lineno = line0;
                switch (token.Lex)
                {
                    case LexType.INTEGER:
                    case LexType.CHAR1:
                        baseType(t);
                        idList(t);
                        match(LexType.SEMI);
                        p = fieldDecMore();
                        break;
                    case LexType.ARRAY:
                        arrayType(t);
                        idList(t);
                        match(LexType.SEMI);
                        p = fieldDecMore();
                        break;
                    default:
                        ReadNextToken();
                        printError(token.lineshow + ":unexpected token is here!");
                        break;
                }
                t.sibling = p;
            }
            return t;
        }
        treeNode fieldDecMore()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.END: break;
                case LexType.INTEGER:
                case LexType.CHAR1:
                case LexType.ARRAY:
                    t = fieldDecList();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }
        void idList(treeNode t)
        {
            if (token.Lex == LexType.ID)
            {
                t.name[(t.idnum)] = token.Sem;
                match(LexType.ID);
                t.idnum = (t.idnum) + 1;
            }
            idMore(t);
        }
        void idMore(treeNode t)
        {
            switch (token.Lex)
            {
                case LexType.SEMI: break;
                case LexType.COMMA:
                    match(LexType.COMMA);
                    idList(t);
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
        }
        treeNode varDec()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.PROCEDURE:
                case LexType.BEGIN: break;
                case LexType.VAR:
                    t = varDeclaration();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }
        treeNode varDeclaration()
        {
            match(LexType.VAR);
            treeNode t = varDecList();
            if (t == null)
                printError(token.lineshow + ":a var declaration is expected!");
            return t;
        }
        treeNode varDecList()
        {
            treeNode t = newSpecificNode(NodeKind.DecK);
            treeNode p = null;

            if (t != null)
            {
                t.lineno = line0;
                typeName(t);
                varIdList(t);
                match(LexType.SEMI);
                p = varDecMore();
                t.sibling = p;
            }
            return t;
        }
        treeNode varDecMore()
        {
            treeNode t = null;

            switch (token.Lex)
            {
                case LexType.PROCEDURE:
                case LexType.BEGIN:
                    break;
                case LexType.INTEGER:
                case LexType.CHAR1:
                case LexType.ARRAY:
                case LexType.RECORD:
                case LexType.ID:
                    t = varDecList();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }
        void varIdList(treeNode t)
        {
            if (token.Lex == LexType.ID)
            {
                t.name[(t.idnum)] = token.Sem;
                match(LexType.ID);
                t.idnum = (t.idnum) + 1;
            }
            else
            {
                printError(token.lineshow + "：a varid is expected here!");
                ReadNextToken();
            }
            varIdMore(t);
        }
        void varIdMore(treeNode t)
        {
            switch (token.Lex)
            {
                case LexType.SEMI: break;
                case LexType.COMMA:
                    match(LexType.COMMA);
                    varIdList(t);
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + "：unexpected token is here!");
                    break;
            }
        }
        treeNode procDec()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.BEGIN: break;
                case LexType.PROCEDURE:
                    t = procDeclaration();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }
        treeNode procDeclaration()
        {
            treeNode t = newSpecificNode(NodeKind.ProcDecK);
            match(LexType.PROCEDURE);
            if (t != null)
            {
                t.lineno = line0;
                if (token.Lex == LexType.ID)
                {
                    t.name[0] = token.Sem;
                    (t.idnum)++;
                    match(LexType.ID);
                }
                match(LexType.LPAREN);
                paramList(t);
                match(LexType.RPAREN);
                match(LexType.SEMI);
                t.child[1] = procDecPart();
                t.child[2] = procBody();
                t.sibling = procDec();
            }
            return t;
        }
        void paramList(treeNode t)
        {
            treeNode p = null;

            switch (token.Lex)
            {
                case LexType.RPAREN: break;
                case LexType.INTEGER:
                case LexType.CHAR1:
                case LexType.ARRAY:
                case LexType.RECORD:
                case LexType.ID:
                case LexType.VAR:
                    p = paramDecList();
                    t.child[0] = p;
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
        }
        treeNode paramDecList()
        {
            treeNode t = param();
            treeNode p = paramMore();
            if (p != null)
            {
                t.sibling = p;
            }
            return t;
        }
        treeNode paramMore()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.RPAREN: break;
                case LexType.SEMI:
                    match(LexType.SEMI);
                    t = paramDecList();
                    if (t == null)
                        printError(token.lineshow + ":a param declaration is request!");
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }
        treeNode param()
        {
            treeNode t = newSpecificNode(NodeKind.DecK);
            if (t != null)
            {
                t.lineno = line0;
                switch (token.Lex)
                {
                    case LexType.INTEGER:
                    case LexType.CHAR1:
                    case LexType.ARRAY:
                    case LexType.RECORD:
                    case LexType.ID:
                        t.attr.ProcAttr.paramt = ParamType.valparamType;
                        typeName(t);
                        formList(t);
                        break;
                    case LexType.VAR:
                        match(LexType.VAR);
                        t.attr.ProcAttr.paramt = ParamType.varparamType;
                        typeName(t);
                        formList(t);
                        break;
                    default:
                        ReadNextToken();
                        printError(token.lineshow + ":unexpected token is here!");
                        break;
                }
            }
            return t;
        }
        void formList(treeNode t)
        {
            if (token.Lex == LexType.ID)
            {
                t.name[(t.idnum)] = token.Sem;
                t.idnum = (t.idnum) + 1;
                match(LexType.ID);
            }
            fidMore(t);
        }
        void fidMore(treeNode t)
        {
            switch (token.Lex)
            {
                case LexType.SEMI:
                case LexType.RPAREN: break;
                case LexType.COMMA:
                    match(LexType.COMMA);
                    formList(t);
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
        }
        treeNode procDecPart()
        {
            treeNode t = declarePart();
            return t;
        }

        treeNode procBody()
        {
            treeNode t = programBody();
            if (t == null)
                printError(token.lineshow + ":a program body is requested!");
            return t;
        }
        treeNode programBody()
        {
            treeNode t = newSpecificNode(NodeKind.StmLK);

            match(LexType.BEGIN);
            if (t != null)
            {
                t.lineno = line0;
                t.child[0] = stmList();
            }
            match(LexType.END);
            return t;
        }
        treeNode stmList()
        {
            treeNode t = stm();
            treeNode p = stmMore();
            if (t != null)
                if (p != null)
                    t.sibling = p;
            return t;
        }

        treeNode stmMore()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.ELSE:
                case LexType.FI:
                case LexType.END:
                case LexType.ENDWH: break;
                case LexType.SEMI:
                    match(LexType.SEMI);
                    t = stmList();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }

        treeNode stm()
        {

            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.IF:
                    t = conditionalStm();
                    break;
                case LexType.WHILE:
                    t = loopStm();
                    break;
                case LexType.READ:
                    t = inputStm();
                    break;
                case LexType.WRITE:
                    t = outputStm();
                    break;
                case LexType.RETURN:
                    t = returnStm();
                    break;
                case LexType.ID:
                    temp_name = token.Sem;
                    match(LexType.ID);
                    t = assCall();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }
        treeNode assCall()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.ASSIGN:
                case LexType.LMIDPAREN:
                case LexType.DOT:
                    t = assignmentRest();
                    break;
                case LexType.LPAREN:
                    t = callStmRest();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }

        treeNode assignmentRest()
        {
            treeNode t = newStmtNode(StmtKind.AssignK);//赋值语句节点，子节点：变量节点和表达式。
            if (t != null)
            {
                t.lineno = line0;
                treeNode child1 = newExpNode(ExpKind.VariK);
                if (child1 != null)
                {
                    child1.lineno = line0;
                    child1.name[0] = temp_name;
                    (child1.idnum)++;
                    variMore(child1);
                    t.child[0] = child1;
                }
                match(LexType.ASSIGN);
                t.child[1] = exp();

            }
            return t;
        }
        treeNode conditionalStm()
        {
            treeNode t = newStmtNode(StmtKind.IfK);
            match(LexType.IF);
            if (t != null)
            {
                t.lineno = line0;
                t.child[0] = exp();
            }
            match(LexType.THEN);
            if (t != null) t.child[1] = stmList();
            if (token.Lex == LexType.ELSE)
            {
                match(LexType.ELSE);
                if (t != null)
                    t.child[2] = stmList();
            }
            match(LexType.FI);
            return t;
        }

        treeNode loopStm()
        {
            treeNode t = newStmtNode(StmtKind.WhileK);/////while节点,子节点:条件表达式和语句序列。
            match(LexType.WHILE);
            if (t != null)
            {
                t.lineno = line0;
                t.child[0] = exp();
                match(LexType.DO);
                t.child[1] = stmList();
                match(LexType.ENDWH);
            }
            return t;
        }

        treeNode inputStm()
        {
            treeNode t = newStmtNode(StmtKind.ReadK);
            match(LexType.READ);
            match(LexType.LPAREN);
            if ((t != null) && (token.Lex == LexType.ID))
            {
                t.lineno = line0;
                t.name[0] = token.Sem;
                (t.idnum)++;
            }
            match(LexType.ID);
            match(LexType.RPAREN);
            return t;
        }
        treeNode outputStm()
        {
            treeNode t = newStmtNode(StmtKind.WriteK);
            match(LexType.WRITE);
            match(LexType.LPAREN);
            if (t != null)
            {
                t.lineno = line0;
                t.child[0] = exp();
            }
            match(LexType.RPAREN);
            return t;
        }

        treeNode returnStm()
        {
            treeNode t = newStmtNode(StmtKind.ReturnK);
            match(LexType.RETURN);
            if (t != null)
                t.lineno = line0;
            return t;
        }

        treeNode callStmRest()
        {
            treeNode t = newStmtNode(StmtKind.CallK);
            match(LexType.LPAREN);
            if (t != null)
            {
                t.lineno = line0;
                treeNode child0 = newExpNode(ExpKind.VariK);
                if (child0 != null)
                {
                    child0.lineno = line0;
                    child0.name[0] = temp_name;
                    (child0.idnum)++;
                    t.child[0] = child0;
                }
                t.child[1] = actParamList();
            }
            match(LexType.RPAREN);
            return t;
        }
        treeNode actParamList()
        {
            treeNode t = null;

            switch (token.Lex)
            {
                case LexType.RPAREN: break;
                case LexType.ID:
                case LexType.INTC:
                    t = exp();
                    if (t != null)
                        t.sibling = actParamMore();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }
        treeNode actParamMore()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.RPAREN: break;
                case LexType.COMMA:
                    match(LexType.COMMA);
                    t = actParamList();
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            return t;
        }
        treeNode exp()
        {
            treeNode t = simple_exp();
            if ((token.Lex == LexType.LT) || (token.Lex == LexType.EQ))
            {
                treeNode p = newExpNode(ExpKind.OpK);
                if (p != null)
                {
                    p.lineno = line0;
                    p.child[0] = t;
                    p.attr.ExpAttr.op = token.Lex;
                    t = p;
                }
                match(token.Lex);
                if (t != null)
                    t.child[1] = simple_exp();
            }
            return t;
        }

        treeNode simple_exp()
        {
            treeNode t = term();
            while ((token.Lex == LexType.PLUS) || (token.Lex == LexType.MINUS))
            {
                treeNode p = newExpNode(ExpKind.OpK);
                if (p != null)
                {
                    p.lineno = line0;
                    p.child[0] = t;
                    p.attr.ExpAttr.op = token.Lex;
                    t = p;
                    match(token.Lex);
                    t.child[1] = term();
                }
            }
            return t;
        }

        treeNode term()
        {
            treeNode t = factor();
            while ((token.Lex == LexType.TIMES) || (token.Lex == LexType.OVER))
            {
                treeNode p = newExpNode(ExpKind.OpK);
                if (p != null)
                {
                    p.lineno = line0;
                    p.child[0] = t;
                    p.attr.ExpAttr.op = token.Lex;
                    t = p;
                }
                match(token.Lex);
                p.child[1] = factor();

            }
            return t;
        }
        treeNode factor()
        {
            treeNode t = null;
            switch (token.Lex)
            {
                case LexType.INTC:
                    t = newExpNode(ExpKind.ConstK);
                    if ((t != null) && (token.Lex == LexType.INTC))
                    {
                        t.lineno = line0;
                        t.attr.ExpAttr.val = StrToInt(token.Sem);
                    }
                    match(LexType.INTC);
                    break;
                case LexType.ID:
                    t = variable();
                    break;
                //(
                case LexType.LPAREN:
                    match(LexType.LPAREN);
                    t = exp();
                    match(LexType.RPAREN);

                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
            /* 函数返回表达式类型语法树节点t */
            return t;
        }
        treeNode variable()
        {
            treeNode t = newExpNode(ExpKind.VariK);

            if ((t != null) && (token.Lex == LexType.ID))
            {
                t.lineno = line0;
                t.name[0] = token.Sem;
                (t.idnum)++;
            }

            match(LexType.ID);
            variMore(t);
            return t;
        }

        void variMore(treeNode t)
        {
            switch (token.Lex)
            {
                case LexType.ASSIGN:
                case LexType.TIMES:
                case LexType.EQ:
                case LexType.LT:
                case LexType.PLUS:
                case LexType.MINUS:
                case LexType.OVER:
                case LexType.RPAREN:
                case LexType.RMIDPAREN:
                case LexType.SEMI:
                case LexType.COMMA:
                case LexType.THEN:
                case LexType.ELSE:
                case LexType.FI:
                case LexType.DO:
                case LexType.ENDWH:
                case LexType.END:
                    break;
                case LexType.LMIDPAREN:
                    match(LexType.LMIDPAREN);
                    t.child[0] = exp();

                    t.attr.ExpAttr.varkind = VarKind.ArrayMembV;
                    t.child[0].attr.ExpAttr.varkind = VarKind.IdV;
                    match(LexType.RMIDPAREN);
                    break;
                case LexType.DOT:
                    match(LexType.DOT);
                    t.child[0] = fieldvar();

                    t.attr.ExpAttr.varkind = VarKind.FieldMembV;

                    t.child[0].attr.ExpAttr.varkind = VarKind.IdV;
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
        }
        treeNode fieldvar()
        {
            treeNode t = newExpNode(ExpKind.VariK);
            if ((t != null) && (token.Lex == LexType.ID))
            {
                t.lineno = line0;
                t.name[0] = token.Sem;
                (t.idnum)++;
            }
            match(LexType.ID);
            fieldvarMore(t);
            return t;
        }
        void fieldvarMore(treeNode t)
        {
            switch (token.Lex)
            {
                case LexType.ASSIGN:
                case LexType.TIMES:
                case LexType.EQ:
                case LexType.LT:
                case LexType.PLUS:
                case LexType.MINUS:
                case LexType.OVER:
                case LexType.RPAREN:
                case LexType.SEMI:
                case LexType.COMMA:
                case LexType.THEN:
                case LexType.ELSE:
                case LexType.FI:
                case LexType.DO:
                case LexType.ENDWH:
                case LexType.END:
                    break;
                case LexType.LMIDPAREN:
                    match(LexType.LMIDPAREN);

                    t.child[0] = exp();
                    t.child[0].attr.ExpAttr.varkind = VarKind.ArrayMembV;
                    match(LexType.RMIDPAREN);
                    break;
                default:
                    ReadNextToken();
                    printError(token.lineshow + ":unexpected token is here!");
                    break;
            }
        }

    }
}
